package com.zjj.lbw.interview.ideology.classify;

/**
 * @author zhanglei.zjj
 * @description 井字游戏
 * 用字符串数组作为井字游戏的游戏板 board，判断该游戏板有没有可能最终形成
 * 游戏板是一个 3 x 3 数组，由字符 " "，"X" 和 "O" 组成。字符 " " 代表一个空位。
 * 两个玩家轮流将字符放入空位，一个玩家执X棋，另一个玩家执O棋
 * “X” 和 “O” 只允许放置在空位中，不允许对已放有字符的位置进行填充。
 * 当有 3 个相同（且非空）的字符填充任何行、列或对角线时，游戏结束，board生成
 * @date 2023/9/8 10:52
 */
public class TicTacToe {
    public static boolean validBoard(String[] board) {
        if (board == null || board.length <= 0) {
            return false;
        }
        int xCount = 0, oCount = 0;
        // 遍历字符数组，统计 x 和 o的数量
        for (String s : board) {
            char[] chars = s.toCharArray();
            for (char charItem : chars) {
                if (charItem == 'X') {
                    xCount++;
                } else if (charItem == 'O') {
                    oCount++;
                }
            }
        }
        // 如果下完是终态，要么XO数量相等（O赢），要么X比O多1（X赢）
        if (xCount != oCount && xCount - oCount != 1) {
            return false;
        }
        // X赢 但是 X的数量又没有比O多1
        if (canWin(board, "XXX") && xCount - oCount != 1) {
            return false;
        }
        // O赢，但是X的数量又没有和O相等
        if (canWin(board, "OOO") && xCount - oCount != 0) {
            return false;
        }

        return true;
    }

    private static boolean canWin(String[] board, String flag) {
        for (int i = 0; i < 3; i++) {
            // - 横线赢
            if (board[i].equals(flag)) {
                return true;
            }

            // | 竖线赢

            if (("" + board[0].charAt(i) + board[1].charAt(i) + board[2].charAt(i)).equals(flag)) {
                return true;
            }

            // / 对角线赢
            if (("" + board[0].charAt(2) + board[1].charAt(1) + board[2].charAt(0)).equals(flag)) {
                return true;
            }

            // \ 对角线赢
            if (("" + board[0].charAt(0) + board[1].charAt(1) + board[2].charAt(2)).equals(flag)) {
                return true;
            }
        }

        return false;
    }

    public static void main(String[] args) {
        System.out.println(validBoard(new String[]{"XXX", "OXO", "O O"}));
    }
}
